use ndarray::{Array1, Array2};
use nalgebra::{DMatrix, DVector};

pub fn solve_by_nalgebra(x: Array2<f64>, y: Array1<f64>) -> Array1<f64> {
    // 1. 将 `ndarray` 转换为 `nalgebra` 的矩阵和向量
    let (rows, cols) = (x.nrows(), x.ncols());
    let x_flat: Vec<f64> = x.iter().cloned().collect();
    let y_flat: Vec<f64> = y.iter().cloned().collect();

    let x_matrix = DMatrix::from_row_slice(rows, cols, &x_flat);
    let y_vector = DVector::from_vec(y_flat);

    // 2. 使用 `nalgebra` 求解线性方程 (x * result = y)
    let lu = x_matrix.lu();
    let solution = lu.solve(&y_vector).expect("矩阵不可逆或方程无解");

    // 3. 将结果转换回 `ndarray` 的 Array1<f64>
    Array1::from(solution.as_slice().to_vec())
}

#[cfg(test)]
#[allow(unused)]
mod test {
    use super::*;
    use ndarray::array;
    use approx::assert_abs_diff_eq;

    #[test]
    fn test_solve() {
        let a = array![
            [4.0, 1.0, 2.0],
            [3.0, 5.0, 1.0],
            [1.0, 1.0, 3.0]
        ];
        let b = array![4.0, 7.0, 3.0];

        let x = solve_by_nalgebra(a, b);
        
        let ans = array![0.5, 1.0, 0.5];
        
        assert_abs_diff_eq!(
            x.as_slice().unwrap(), 
            ans.as_slice().unwrap(),
            epsilon = 1e-9
        );
    }
}